﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.IO;
using System.Linq;
using System.Text;

namespace CreateFileCode
{
    class Program
    {
        static Library.Common s = new Library.Common();
        static List<Library.TableModel> Tables = new List<Library.TableModel>();
        static List<Library.ColumnModel> columnList = new List<Library.ColumnModel>();
        static Dictionary<string, List<Library.ColumnModel>> Columns = new Dictionary<string, List<Library.ColumnModel>>();
        static string HostNameSpace = System.Configuration.ConfigurationManager.AppSettings["NameSpace"].Trim();
        static Dictionary<string, Guid> ProjectGuid = new Dictionary<string, Guid>();
        static string TableList = System.Configuration.ConfigurationManager.AppSettings["TableList"].Trim();
        /// <summary>
        /// 表名
        /// </summary>
        private static string _tableName=string.Empty;
        /// <summary>
        /// 文件要存放的路径
        /// </summary>
        private static string _path = System.Configuration.ConfigurationManager.AppSettings["ToPath"].Trim();
        /// <summary>
        /// 生成文件所放路径
        /// </summary>
        private static string _toPath;
        /// <summary>
        /// 模板文件路径
        /// </summary>
        private static string _tmpPath =AppDomain.CurrentDomain.BaseDirectory + "\\Template";
        static void Main(string[] args)
        {
            InputConfig();
            UpdateAppConfig("ToPath", _toPath);
            UpdateAppConfig("NameSpace",HostNameSpace);
            CreateCode("Model");//创建该类型项目的文件
        }
        static void UpdateAppConfig(string newKey, string newValue)
        {
            var isModified = ConfigurationManager.AppSettings.Cast<string>().Any(key => key == newKey);
            var config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
            if (isModified) config.AppSettings.Settings.Remove(newKey);
            config.AppSettings.Settings.Add(newKey, newValue);
            config.Save(ConfigurationSaveMode.Modified);
            ConfigurationManager.RefreshSection("appSettings");
        }
        static void InputConfig()
        {
            Console.Write("请输入文件存放路径：");
            _toPath = Console.ReadLine();
            if (string.IsNullOrWhiteSpace(_toPath))
            {
                _toPath = _path;
                if (string.IsNullOrWhiteSpace(_toPath))
                    _toPath = AppDomain.CurrentDomain.BaseDirectory + "\\GenerateFile";
                Console.WriteLine("文件默认存放位置：{0}", _toPath);
            }
            else if (_toPath.ToLower() == "quit")
            {
                Environment.Exit(0);
            }
            else
            {
                while (_toPath != null && !Directory.Exists(_toPath))
                {
                    Console.Write("输入的路径无效，请重新输入：");
                    _toPath = Console.ReadLine();
                }
                Console.WriteLine("文件存放位置：{0}", _toPath);
            }
            Console.WriteLine();
            Console.Write("请输入命名空间:");
            HostNameSpace = Console.ReadLine();
            if (string.IsNullOrWhiteSpace(HostNameSpace))
            {
                HostNameSpace = System.Configuration.ConfigurationManager.AppSettings["NameSpace"].Trim();
                Console.WriteLine("默认命名空间：{0}", HostNameSpace);
            }
            else if (HostNameSpace.ToLower() == "quit")
            {
                Environment.Exit(0);
            }
            else
            {
                Console.WriteLine("命名空间：{0}", HostNameSpace);
            }
            Console.WriteLine();
            Console.Write("请输入表名(支持模糊查询)：");
            _tableName = Console.ReadLine();
            while (string.IsNullOrWhiteSpace(_tableName))
            {
                Console.Write("表名无效，请重新输入：");
                _tableName = Console.ReadLine();
                if (_tableName != null && _tableName.ToLower() == "quit")
                {
                    Environment.Exit(0);
                }
            }
        }
        static void Init()
        {
            var dt = s.GetTableList(_tableName);
            foreach (DataRow item in dt.Rows)
            {
                var tableName = item["table_name"].ToString();
                if (!string.IsNullOrWhiteSpace(TableList) && !TableList.Contains(tableName))
                    continue;
                var dtt = s.GetExendedPropretyOfColumns(tableName);
                var tableDesc = s.GetExtendedPropertyOfTable(tableName);
                var tm = new Library.TableModel()
                {
                    Name = tableName,
                    Description = string.IsNullOrWhiteSpace(tableDesc) ? tableName : tableDesc
                };
                tm.Name = UpFirstChar(tm.Name);
                var list = new List<Library.ColumnModel>();
                foreach (DataRow c in dtt.Rows)
                {
                    var cm = new Library.ColumnModel()
                    {
                        ID = Convert.ToInt32(c["cid"]),
                        Name = c["cname"].ToString(),
                        Type = c["type"].ToString(),
                        IsNull = Convert.ToBoolean(c["isnull"]),
                        IsPrimary = Convert.ToBoolean(c["ispk"]),
                        IsIdentity = Convert.ToBoolean(c["isidentity"]),
                        ByteLength = Convert.ToInt32(c["bytelength"]),
                        Length = Convert.ToInt32(c["length"]),
                        Default = c["dvalue"].ToString(),
                        Description = c["desc"].ToString(),
                        DecimalPlaces = Convert.ToInt32(c["DecimalPlaces"])
                    };
                    cm.Name = UpFirstChar(cm.Name);
                    if (cm.IsPrimary)
                        tm.Primary = string.IsNullOrWhiteSpace(tm.Primary) ? cm.Name : tm.Primary + "," + cm.Name;
                    columnList.Add(cm);
                    list.Add(cm);
                }
                tm.Primary = string.IsNullOrWhiteSpace(tm.Primary) ? "id" : tm.Primary;
                Columns.Add(tableName.ToLower(), list);
                Tables.Add(tm);
            }
        }
        static void CreateCode(string projectType)
        {
            Init();
            Create(UpFirstChar(projectType));
        }
        static void Create(string projectName)
        {
            var s = File.ReadAllText(_tmpPath+"\\" + projectName + ".txt");
            var fsb = new StringBuilder();

            foreach (var item in Tables)
            {
                if (item.Name.IndexOf("-") > -1) continue;
                var sb = new StringBuilder(s);
                sb.Replace("$NameSpace$", HostNameSpace);
                sb.Replace("$TableName$", item.Name);
                sb.Replace("$Primary$", item.Primary);
                sb.Replace("$TableDescription$", item.Description);
                if (s.IndexOf("$PropertyList$") > -1)
                {
                    var psb = new StringBuilder();
                    var tmp = @"

        /// <summary>
        /// {3} {5} {2}({0}) {4}允许为空
        /// </summary>
        public {1} {0}";
                    foreach (var c in Columns[item.Name.ToLower()])
                    {
                        psb.AppendFormat(tmp, c.Name, Library.Common.ChangeToCSharpType(c.Type), c.Description,
                                     c.IsPrimary ? "主键" : string.Empty, c.IsNull ? string.Empty : "不", c.IsIdentity ? "标识" : string.Empty
                                     ).Append(" { get; set; }");
                    }
                    sb.Replace("$PropertyList$", psb.ToString());
                }
                if (s.IndexOf("$SetProperties$") > -1)
                {
                    var spsb = new StringBuilder();
                    foreach (var c in Columns[item.Name.ToLower()])
                    {
                        var ty = Library.Common.ChangeToCSharpType(c.Type);
                        spsb.AppendFormat(@"
                {0} = DataBaseHelp.Get{1}Value(dr, ""{0}""),", c.Name, ty == "string" ? "" : UpFirstChar(ty));
                    }
                    if (spsb.Length > 0) spsb = spsb.Remove(spsb.Length - 1, 1);

                    sb.Replace("$SetProperties$", spsb.ToString());
                }
                var fileName = string.Empty;
                if (projectName.Equals("idal", StringComparison.CurrentCultureIgnoreCase))
                    fileName = "I" + item.Name;
                else if (projectName.Equals("database", StringComparison.CurrentCultureIgnoreCase))
                    fileName = "DB" + item.Name;
                else if (projectName.Equals("library", StringComparison.CurrentCultureIgnoreCase))
                    fileName = @"page\" + item.Name;
                else
                    fileName = item.Name;
                //fsb.AppendFormat("<Compile Include=\"{0}.cs\" />\n", fileName);
                var path = _toPath+"\\" + fileName + ".cs";
                CreateFile(path, sb.ToString());
            }
            //var p = CreateProjectFile(projectName, fsb.ToString());
            //CreateFile(d + @"\" + HostNameSpace + "." + projectName + ".csproj", p);
        }
        static void CreateFile(string filePath, string content)
        {
            var d = Path.GetDirectoryName(filePath);
            if (!Directory.Exists(d)) Directory.CreateDirectory(d);
            if (File.Exists(filePath)) File.Delete(filePath);
            using (StreamWriter fsdc = new StreamWriter(filePath, true, Encoding.UTF8))
            {
                fsdc.WriteLine(content);
                fsdc.Close();
            }
        }
        static string UpFirstChar(string str)
        {
            return str = str.Substring(0, 1).ToUpper() + str.Substring(1);
        }
    }
}
